import { Accordion, Alert, Image } from '@aws-amplify/ui-react';

import { ComponentStyleDisplay } from '@/components/ComponentStyleDisplay';
import { Example, ExampleCode } from '@/components/Example';
import { InlineFilter } from '@/components/InlineFilter';
import AppDirectoryAlert from '@/components/AppDirectoryAlert';
import { InstallScripts } from '@/components/InstallScripts';
import ReactPropsTable from '@/components/propsTable/ReactPropsTable';
import { STORAGE_IMAGE } from './props';

## Basic Usage

<Alert variation="warning" heading="Wait!">
  Did you follow the [quick start instructions](/connected-components/storage#quick-start) to set up the storage and auth services?
</Alert>

<InlineFilter filters={['react']}>
  <AppDirectoryAlert />
</InlineFilter>

To use the StorageImage component, import it into your React application with the included styles. 

<InstallScripts component="storage" />

<ExampleCode>
```js
import { StorageImage } from '@aws-amplify/ui-react-storage';
import '@aws-amplify/ui-react/styles.css';
```
</ExampleCode>

At a minimum you must include the `alt` and `path` props. `path` is a full S3 object key and refers to the Amplify Storage path (See [Download Files](https://docs.amplify.aws/react/build-a-backend/storage/download-files/)). It is either a `string` or a callback function that accepts the current user's Cognito `identityId` and returns a `string`.

### Public Image
<Example>
  <Image alt='cat' src='/cats/1.jpg' width="400px" height="400px" />
  <ExampleCode>
    ```jsx file=./examples/Default.tsx
    ```
  </ExampleCode>
</Example>

### Private or Protected Image
When using private or protected images, you'll need to wrap your app in the `Authenticator`, allowing the `StorageImage` component to infer the Cognito `identityId` of the currently signed-in user. This can be done directly with the `Authenticator` component or with `withAuthenticator`, as shown in [Add the Authenticator](/connected-components/authenticator#step-3-add-the-authenticator).
<Example>
  <Image alt='cat' src='/cats/1.jpg' width="400px" height="400px" />
  <ExampleCode>
    ```jsx file=./examples/Protected.tsx
    ```
  </ExampleCode>
</Example>

### Deprecated props
<Accordion.Container>
  <Accordion.Item key={"title"} value={"title"}>
    <Accordion.Trigger>
      Using `@aws-amplify/ui-react-storage` version 3.0.18 or below?
      <Accordion.Icon />
    </Accordion.Trigger>
    <Accordion.Content>
      Versions 3.0.18 and earlier use `imgKey`, `accessLevel`, and `identityId` in place of the `path` prop.
      ```tsx
      <StorageImage 
         alt="sleepy-cat" 
         accessLevel="guest" 
         imgKey="cat.jpg" 
      />

       <StorageImage 
         alt="sleepy-cat" 
         accessLevel="private"
         identityId={identityId} 
         imgKey="cat.jpg" 
      />
      ```
    </Accordion.Content>
  </Accordion.Item>
</Accordion.Container>

## Props

<ReactPropsTable props={STORAGE_IMAGE} />

## Error Handling

To handle the error caused by `Storage.get`, you can pass a `onGetUrlError` handler and optionally provide a `fallbackSrc` for the component to load a fallback image.

<Example>
 <Image alt='fallback cat' src='/cats/2.jpg' width="400px" height="400px" />
  <ExampleCode>
    ```jsx file=./examples/ErrorHandling.tsx
    ```
  </ExampleCode>
</Example>

### Deprecated props
<Accordion.Container>
  <Accordion.Item key={"title"} value={"title"}>
    <Accordion.Trigger>
      Using `@aws-amplify/ui-react-storage` version 3.0.18 or below?
      <Accordion.Icon />
    </Accordion.Trigger>
    <Accordion.Content>
      Versions 3.0.18 and earlier use `onStorageGetError` in place of the `onGetUrlError` prop.
    ```tsx
    <StorageImage
       alt="fallback cat"
       accessLevel="guest"
       imgKey="cat.jpg"
       fallbackSrc="/fallback_cat.jpg"
       onStorageGetError={(error) => console.error(error)}
    />
    ```
    </Accordion.Content>
  </Accordion.Item>
</Accordion.Container>

## Customization

### Target Classes
<ComponentStyleDisplay componentName="StorageImage" />
